﻿using SameGame.Presentation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SameGame
{
	/// <summary>
	/// Interaction logic for BoardUserControl.xaml
	/// </summary>
	public partial class BoardUserControl : UserControl, IBoardView
	{
		const int _itemSize = 40;

		private IBoardPresenter _presenter;
		private List<BallUserControl> _balls;
		private List<BallUserControl> _removingBalls;

		public BoardUserControl(IBoardPresenter presenter)
		{
			_balls = new List<BallUserControl>();
			_removingBalls = new List<BallUserControl>();

			InitializeComponent();

			_presenter = presenter;
			_presenter.View = this;
		}

		public void ShowItem(int column, int row, int colorType)
		{
			BallUserControl ball = FindBall(column, row);

			if (ball == null) {
				ball = new BallUserControl(this);
				ball.Width = _itemSize;
				ball.Height = _itemSize;
				ball.Column = column;
				ball.Row = row;

				_balls.Add(ball);

				canvas.Children.Add(ball);
				Canvas.SetLeft(ball, column * _itemSize);
				Canvas.SetTop(ball, row * _itemSize);
			}
			ball.ColorType = colorType;
		}

		private BallUserControl FindBall(int column, int row)
		{
			foreach (BallUserControl ball in _balls) {
				if (ball.Column == column && ball.Row == row)
					return ball;
			}
			return null;
		}

		public void ClearHighlights()
		{
			foreach (BallUserControl ball in _balls) {
				ball.IsHighlighted = false;
			}
		}

		public void Highlight(int column, int row, bool isHighlighted)
		{
			BallUserControl ball = FindBall(column, row);
			if (null != ball) {
				ball.IsHighlighted = isHighlighted;
			}
		}

		internal void OnEnterHighlight(int column, int row)
		{
			_presenter.Highlight(column, row);
		}

		internal void OnLeaveHighlight(int column, int row)
		{
			ClearHighlights();
			HideAvailableScore();
		}

		internal void OnBallClick(int column, int row)
		{
			_presenter.Remove(column, row);
		}

		public void RemoveBall(int column, int row)
		{
			BallUserControl ball = FindBall(column, row);

			DoubleAnimation animation = new DoubleAnimation();
			animation.From = _itemSize - 5;
			animation.To = 0;
			animation.Duration = new Duration(TimeSpan.FromSeconds(0.5));

			animation.Completed += animation_Completed;

			_balls.Remove(ball);
			ball.ClearEvents();
			_removingBalls.Add(ball);
			ball.ellipse.BeginAnimation(BallEllipseUserControl.WidthProperty, animation);
			ball.ellipse.BeginAnimation(BallEllipseUserControl.HeightProperty, animation);
		}

		void animation_Completed(object sender, EventArgs e)
		{
			BallUserControl ball = null;
			foreach (BallUserControl b in _removingBalls) {
				if (b.ellipse.Height == 0 && b.ellipse.Width == 0)
				{
					ball = b;
					break;
				}
			}
			if (ball != null) {

				canvas.Children.Remove(ball);
				_removingBalls.Remove(ball);
			}
		}

		public void DeleteBalls()
		{
			_balls.Clear();
			canvas.Children.Clear();
		}

		public int Rows
		{
			set { canvas.Height = value * _itemSize; }
		}

		public int Columns
		{
			set { canvas.Width = value * _itemSize; }
		}

		public void MoveBall(int column, int row, int newColumn, int newRow)
		{
			BallUserControl ball = FindBall(column, row);

			ball.Column = newColumn;
			ball.Row = newRow;
			Canvas.SetLeft(ball, newColumn * _itemSize);
			//Canvas.SetTop(ball, newRow * _itemSize);

			DoubleAnimation animation = new DoubleAnimation();
			animation.From = row * _itemSize;
			animation.To = newRow * _itemSize;
			animation.Duration = new Duration(TimeSpan.FromSeconds(0.5));

			ball.BeginAnimation(Canvas.TopProperty, animation);

			DoubleAnimation animationColumn = new DoubleAnimation();
			animation.From = column * _itemSize;
			animation.To = newColumn * _itemSize;
			animation.Duration = new Duration(TimeSpan.FromSeconds(0.5));

			ball.BeginAnimation(Canvas.LeftProperty, animation);
		}

		public void ShowAvailableScore(int score)
		{
			ToolTip = score;
		}

		public void HideAvailableScore()
		{
			ToolTip = null;
		}
	}
}
